from Tkinter import Tk 
from Tkinter import Frame
from Tkinter import Entry
from Tkinter import Label
from Tkinter import TOP
from Tkinter import Button
from Tkinter import RIGHT
from vtk.tk.vtkTkRenderWidget import *
import VTK
import time

class TkinterFrame():
    
    '''
    Setting private atr and globals
    '''
    __loopRunning = False
    __exitRequested = False
    __timeStep=0.1
    __renderWindow = None
    __defaultButtonPushed = False
    
    global ipEntry, portEntry, minMassEntry, maxMassEntry, minRadiEntry 
    global maxRadiEntry, minRangeEntry, maxRangeEntry, numberOfBodiesEntry 
    global centralStarMassEntry  
    
    def __init__(self, client):
        '''
        Saving client Instance
        '''
        self.__clientIns = client
        
        
    def loadTkinter(self):
        '''
        Loading Tkinter with Lables, Entrys, Buttons
        '''
        self.__root = Tk()
        self.__root.title('Mehrkoerpersystem') 
        self.__root.protocol("WM_DELETE_WINDOW", quit)
        self.__vtk = VTK.VTK()
        self.createEntry()
        self.createLable()
        self.__vtk.startRenderer()
        self.__ren = self.__vtk.getRenderer()
        self.addRenderWidget()
        self.addDefaultButton()
        self.addStartButton()
        self.addQuitButton()
        self.__root.mainloop()
        
    def startTkinter(self):
        '''
        Starting Tkinter and ask if DefaultButton was pushed
        If not, give Warning
        '''
        if self.__defaultButtonPushed == False:
            print 'Bitte Default Button druecken'
            return
        self.__printer = self.__clientIns.getPrinter()
        self.__clientIns.startPrinter()
        self.__bodyList = self.__printer.getBodyStructList()       
        self.__vtk.startVTK(int(self.getNumberOfBodiesEntry()), self.__bodyList)
        self.renderSimulation()
           
    def quit(self):
        '''
        Quitting Tkinter
        '''
        if self.__loopRunning:
            self.__exitRequested = True    
        else:
            self.__root.quit()
    
    def renderSimulation(self):
        '''
        Main Loop, setting for each Body new Positions
        until Quit Button will be pushed and loopRunning = False
        '''
        self.__vtk.setRadi()              
        self.__loopRunning = True
        while not self.__exitRequested:
            time.sleep(self.__timeStep)               
            if self.__printer.calcOneStep() == 1:   
                bodyList = self.__printer.getBodyStructList()
            for i in range(0,len(bodyList)-1):
                positionx = bodyList[i].posX
                positiony = bodyList[i].posY
                positionz = bodyList[i].posZ
                sphereList = self.__vtk.getSphereList()
                sphereList[i].SetPosition(positionx, positiony, positionz)
                self.__renderWindow.Render()
                self.__root.update() 
        self.__root.quit()
    
    def addRenderWidget(self):
        '''
        Adding Render Widget, setting size, setting position
        '''
        ren = self.__vtk.getRenderer()
        renderWidget = vtkTkRenderWidget(self.__root, width = 500, height = 500)
        self.__renderWindow = renderWidget.GetRenderWindow()
        self.__renderWindow.AddRenderer(ren)   
        self.__renderWindow.SetSize(300, 300)
        renderWidget.pack(expand = 'true', fill = 'both') 
        
    def createEntry(self):
        '''
        Adding all needed Entrys
        '''
        global ipEntry, portEntry, minMassEntry, maxMassEntry, minRadiEntry 
        global maxRadiEntry, minRangeEntry, maxRangeEntry, numberOfBodiesEntry 
        global centralStarMassEntry 
        
        entryFrame = Frame(self.__root)
        ipEntry = Entry(entryFrame)   
        ipEntry.pack(side = TOP)
        portEntry = Entry(entryFrame)
        portEntry.pack(side = TOP)
        minMassEntry = Entry(entryFrame)
        minMassEntry.pack(side = TOP)
        maxMassEntry = Entry(entryFrame)
        maxMassEntry.pack(side = TOP)
        minRadiEntry = Entry(entryFrame)
        minRadiEntry.pack(side = TOP)
        maxRadiEntry = Entry(entryFrame)
        maxRadiEntry.pack(side = TOP) 
        minRangeEntry = Entry(entryFrame)    
        minRangeEntry.pack(side = TOP)
        maxRangeEntry = Entry(entryFrame)
        maxRangeEntry.pack(side = TOP)
        numberOfBodiesEntry = Entry(entryFrame)
        numberOfBodiesEntry.pack(side = TOP)
        centralStarMassEntry = Entry(entryFrame)
        centralStarMassEntry.pack(side = TOP)
        entryFrame.pack(side = RIGHT)
    
    def createLable(self):
        '''
        Adding all needed Entrys
        '''
        labelFrame = Frame(self.__root)
        ipLabel = Label(labelFrame, text="IP:")
        ipLabel.pack(side=TOP, ipady = 1)
        portLabel = Label(labelFrame, text="Port:")
        portLabel.pack(side= TOP, ipady = 1)
        minMassLabel = Label(labelFrame, text = "Min_Mass_Exp:")
        minMassLabel.pack(side= TOP, ipady = 1)
        maxMassLabel = Label(labelFrame, text = "Max_Mass_Exp:")
        maxMassLabel.pack(side= TOP, ipady = 1)
        minRadiLabel = Label(labelFrame, text = "Min_Radius_Exp:")
        minRadiLabel.pack(side= TOP, ipady = 1)
        maxRadiLabel = Label(labelFrame, text = "Max_Radius_Exp:")
        maxRadiLabel.pack(side= TOP, ipady = 1)
        minRangeLabel = Label(labelFrame, text = "Min_Raumausdehnung_Exp:")
        minRangeLabel.pack(side= TOP, ipady = 1)
        maxRangeLabel = Label(labelFrame, text = "Max_Raumausdehnung_Exp:")
        maxRangeLabel.pack(side= TOP, ipady = 1)
        numberOfBodiesLabel = Label(labelFrame, text = "Anzahl_der_Koerper:")
        numberOfBodiesLabel.pack(side= TOP, ipady = 1)
        centralStarLabel = Label(labelFrame, text = "Masse_Zentralgestirn:")
        centralStarLabel.pack(side= TOP, ipady = 1)    
        labelFrame.pack(side = RIGHT, expand = False)
        
    def addDefaultButton(self):
        '''
        Adding DefaultButton
        '''
        defaultButton = Button(self.__root, text = 'Standardsystem_einrichten'
                                ,command = self.setDefaultParams)
        defaultButton.pack(expand = 'true', fill = 'x')
        
        
    def addStartButton(self):
        '''
        Adding StartButton
        '''
        startButton = Button(self.__root, text = 'Start', command = self.startTkinter)
        startButton.pack(expand = 'true', fill = 'x')
    
    
    def addQuitButton(self):
        '''
        Adding QuitButton
        '''
        quitButton = Button(self.__root, text = "Quit", command = self.quit)
        quitButton.pack(expand = 'true', fill = 'x')
        
    def getIpEntry(self):
        global ipEntry
        return ipEntry.get()
    
    def getPortEntry(self):
        global portEntry
        return portEntry.get()
    
    def getMinMassEntry(self):
        global minMassEntry
        return minMassEntry.get()    

    def getMaxMassEntry(self):
        global maxMassEntry
        return maxMassEntry.get()    
    
    def getMinRadiEntry(self):
        global minRadiEntry
        return minRadiEntry.get()    
    
    def getMaxRadiEntry(self):
        global maxRadiEntry
        return maxRadiEntry.get()            
    
    def getMinRangeEntry(self):
        global minRangeEntry
        return minRangeEntry.get()      
    
    def getMaxRangeEntry(self):
        global maxRangeEntry
        return maxRangeEntry.get()      
    
    def getNumberOfBodiesEntry(self):
        global numberOfBodiesEntry
        return numberOfBodiesEntry.get() 
    
    def getCentralMassStarEntryEntry(self):
        global centralStarMassEntry
        return centralStarMassEntry.get()     
    
    def setDefaultParams(self):
        '''
        Delete all Entrys and insert new default Values
        '''
        self.__defaultButtonPushed = True
        global ipEntry, portEntry, minMassEntry, maxMassEntry, minRadiEntry 
        global maxRadiEntry, minRangeEntry, maxRangeEntry, numberOfBodiesEntry  
        global centralStarMassEntry  
        ipEntry.delete(0, 100)
        portEntry.delete(0, 100)
        minMassEntry.delete(0, 100)
        maxMassEntry.delete(0, 100)
        minRadiEntry.delete(0, 100)
        maxRadiEntry.delete(0, 100)
        minRangeEntry.delete(0, 100)
        maxRangeEntry.delete(0, 100)
        numberOfBodiesEntry.delete(0, 100)
        centralStarMassEntry.delete(0, 100)
        
        ipEntry.insert(1, 'kronosGRBV.informatik.fh-augsburg.de')
        portEntry.insert(1, '10018')
        minMassEntry.insert(1, '22')
        maxMassEntry.insert(1, '27')
        minRadiEntry.insert(1, '6')
        maxRadiEntry.insert(1, '7')
        minRangeEntry.insert(1, '9')
        maxRangeEntry.insert(1, '12')
        numberOfBodiesEntry.insert(1, '6')
        centralStarMassEntry.insert(1, '2E30') 